﻿
Imports freclust
Imports fcesdiskslice_atom = planet.storageJobConsumerInternal.fcesdiskslice_atom(Of _false)
Imports fcesdiskslice = planet.storageJobConsumerInternal.fcesdiskslice(Of _false)

Namespace storageJobConsumerInternal
    Friend Class fceslite
        Inherits fceslite(Of _true)
    End Class

    Public Class diskslice3
        Inherits fcesdiskslice
        Private Const randomClusterId As Int64 = maxInt64
        Private ReadOnly fces As fceslite = Nothing

        Shared Sub New()
            assert(randomClusterId <> freclust.cluster.INVALID)
        End Sub

        Protected Overrides Function meta(ByVal atom As fcesdiskslice_atom, ByVal buff As bytes) As bytes
            atom.clusterId() = randomClusterId
            Return Nothing
        End Function

        Private Shared Sub workOn(ByVal d As _do(Of Boolean),
                                  ByVal result As pointer(Of Boolean),
                                  ByVal cb As void)
            assert(Not d Is Nothing)
            assert(Not cb Is Nothing)
            managedThreadPool.global.insertJob(Sub(_NIU_ As Object)
                                                   eva(result, d())
                                                   cb()
                                               End Sub,
                                               Nothing)
        End Sub

        Private Overloads Shared Function meta(ByVal id As Int64) As bytes
            assert(id <> freclust.cluster.INVALID)
            Return convertor.tobytes(id)
        End Function

        Protected Overrides Function fcesfolder() As String
            Return "fces"
        End Function

        Protected Overrides Function read(ByVal atom As fcesdiskslice_atom,
                                          ByVal result As pointer(Of bytes)) As eventComb
            Dim cb As void = Nothing
            Dim p As pointer(Of Boolean) = Nothing
            Dim rst As bytes = Nothing
            Return New eventComb(Function() As Boolean
                                     Return waitfor(cb) AndAlso
                                            true_(Sub()
                                                      p = New pointer(Of Boolean)(False)
                                                      workOn(Function() As Boolean
                                                                 Return fces.read(atom.clusterId(), rst)
                                                             End Function,
                                                             p,
                                                             cb)
                                                  End Sub) AndAlso
                                            goto_next()
                                 End Function,
                                 Function() As Boolean
                                     Return +p AndAlso
                                            eva(result, rst) AndAlso
                                            goto_end()
                                 End Function)
        End Function

        Protected Overrides Function sizeof(ByVal atom As fcesdiskslice_atom) As Int64
            Dim size As Int64 = 0
            If fces.sizeof(atom.clusterId(), size) Then
                Return size
            Else
                Return npos
            End If
        End Function

        Private Function confirm_clusterId(ByVal p As pointer(Of Boolean),
                                           ByVal id As Int64,
                                           ByVal atom As fcesdiskslice_atom,
                                           ByRef ec As eventComb) As Boolean
            If +p Then
                assert(id <> freclust.cluster.INVALID)
                If id <> atom.clusterId() Then
                    atom.clusterId() = id
                    ec = write_meta(meta(id), atom)
                    Return waitfor(ec) AndAlso
                           goto_next()
                Else
                    Return goto_end()
                End If
            Else
                Return False
            End If
        End Function

        Private Delegate Function aw_delegate(ByVal oid As Int64, ByVal buff As bytes, ByRef nid As Int64) As Boolean
        Private Function aw(ByVal atom As fcesdiskslice_atom,
                            ByVal buff As bytes,
                            ByVal d As aw_delegate) As eventComb
            assert(Not atom Is Nothing)
            assert(Not buff Is Nothing)
            assert(Not d Is Nothing)
            Dim cb As void = Nothing
            Dim p As pointer(Of Boolean) = Nothing
            Dim id As Int64 = freclust.cluster.INVALID
            Dim metaec As eventComb = Nothing
            Return New eventComb(Function() As Boolean
                                     Return waitfor(cb) AndAlso
                                            true_(Sub()
                                                      p = New pointer(Of Boolean)()
                                                      workOn(Function() As Boolean
                                                                 Return d(atom.clusterId(), buff, id)
                                                             End Function,
                                                             p,
                                                             cb)
                                                  End Sub) AndAlso
                                            goto_next()
                                 End Function,
                                 Function() As Boolean
                                     Return confirm_clusterId(p, id, atom, metaec)
                                 End Function,
                                 Function() As Boolean
                                     Return metaec.end_result() AndAlso
                                            goto_end()
                                 End Function)
        End Function

        Protected Overrides Function append(ByVal atom As fcesdiskslice_atom, ByVal buff As bytes) As eventComb
            Return aw(atom, buff, AddressOf fces.append)
        End Function

        Protected Overrides Function write(ByVal atom As fcesdiskslice_atom, ByVal buff As bytes) As eventComb
            Return aw(atom, buff, AddressOf fces.write)
        End Function

        Protected Overrides Function modify(ByVal atom As fcesdiskslice_atom, ByVal buff As bytes) As eventComb
            Return write(atom, buff)
        End Function

        Protected Overrides Function delete(ByVal atom As fcesdiskslice_atom) As eventComb
            Dim cb As void = Nothing
            Dim p As pointer(Of Boolean) = Nothing
            Dim id As Int64 = freclust.cluster.INVALID
            Return New eventComb(Function() As Boolean
                                     Return waitfor(cb) AndAlso
                                            true_(Sub()
                                                      p = New pointer(Of Boolean)()
                                                      workOn(Function() As Boolean
                                                                 Return fces.delete(atom.clusterId())
                                                             End Function,
                                                             p,
                                                             cb)
                                                  End Sub) AndAlso
                                            goto_end()
                                 End Function)
        End Function

        Protected Overrides Function open_fces(ByVal file As String, ByVal buffSize As Int32) As Boolean
            Return fces.open(file, buffSize)
        End Function

        Protected Overrides Function close_fces() As Boolean
            Return fces.close()
        End Function

        Protected Overrides Function version() As String
            Return "Hzj_jie-Gemini-FreeCluster"
        End Function

        Protected Overrides Sub flush()
            assert(fces.flush())
        End Sub

        Public Sub New()
            fces = New fceslite()
        End Sub

        Public Shared Shadows Function initial(ByVal name As String,
                                               ByVal config As configParser,
                                               ByVal c As diskslice3) As Boolean
            Return fcesdiskslice.initial(name, config, convertor.cast(Of fcesdiskslice)(c))
        End Function
    End Class
End Namespace
